#include "user_include.h"

// 1block=16sector(4K)
// 1sector=16page(256)
static osSemaphoreId_t sid_Semaphore_tx;
static osSemaphoreId_t sid_Semaphore_rx;
static void w24q64_init(void);
static void user_tx_cpl_callback(void);
static void user_rx_cpl_callback(void);
static void w24q64_task(void);
struct driver_w25qxx_struct_def driver_w25qxx_struct = {
    .init = w24q64_init,
    .erase_chip = W25qxx_EraseChip,
    .erase_sector = W25qxx_EraseSector,
    .erase_block = W25qxx_EraseBlock,

    .write_byte = W25qxx_WriteByte,
    .write_page = W25qxx_WritePage,
    .write_sector = W25qxx_WriteSector,
    .write_block = W25qxx_WriteBlock,

    .read_byte = W25qxx_ReadByte,
    .read_page = W25qxx_ReadPage,
    .read_sector = W25qxx_ReadSector,
    .read_block = W25qxx_ReadBlock,
    .task = w24q64_task,
    .tx_cpl_callback = user_tx_cpl_callback,
    .rx_cpl_callback = user_rx_cpl_callback,
};
static void w24q64_init(void)
{
    sid_Semaphore_tx = osSemaphoreNew(1U, 0U, NULL);
    sid_Semaphore_rx = osSemaphoreNew(1U, 0U, NULL);
    W25qxx_Init();
}

/****************************************************************************
 * name:XferCpltCallback
 * function: dma send complete callback function
 * in parameters : hdma
 * out parameters : no
 ****************************************************************************/
static void user_tx_cpl_callback(void)
{
    osSemaphoreRelease(sid_Semaphore_tx);
}

/****************************************************************************
 * name:XferCpltCallback
 * function: dma rx complete callback function
 * in parameters : hdma
 * out parameters : no
 ****************************************************************************/
static void user_rx_cpl_callback(void)
{
    osSemaphoreRelease(sid_Semaphore_rx);
}

int32_t usr_spi_write(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
    osStatus_t val;
    uint32_t ret = 0;
    HAL_StatusTypeDef val0;
    osStatus_t val1;

    val0 = HAL_SPI_Transmit_DMA(hspi, pData, Size);
    if (val0 != HAL_OK)
    {
        ret = 1;
    }

    val1 = osSemaphoreAcquire(sid_Semaphore_tx, 10U);
    if (val1 != osOK)
    {
        ret = 1;
    }
    return ret;
}

int32_t usr_spi_read(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
    osStatus_t val;
    uint32_t ret = 0;
    HAL_StatusTypeDef val0;
    osStatus_t val1;

    val0 = HAL_SPI_Receive_DMA(hspi, pData, Size);
    if (val0 != HAL_OK)
    {
        ret = 1;
    }

    val1 = osSemaphoreAcquire(sid_Semaphore_rx, 10U);
    if (val1 != osOK)
    {
        ret = 1;
    }
    return ret;
}
#define SIZE 4096
#define CYCLE 256
static void w24q64_task(void)
{
    static int8_t table[SIZE];
    static int8_t table1[SIZE];
    int16_t i = 0, j = 0;
    driver_w25qxx_struct.init();
    while (1)
    {

        driver_w25qxx_struct.erase_sector(0); // 256 block
        for (i = 0; i < SIZE; i++)
        {
            table[i] = 1;
        }

        for (j = 0; j < CYCLE; j++)
        {

            driver_w25qxx_struct.write_block(table, j, 0, SIZE);
#if 1
            driver_w25qxx_struct.read_block(table1, j, 0, SIZE);
            for (i = 0; i < SIZE; i++)
            {
                if (table[i] != table1[i])
                    goto temp;
            }
#endif
        }
    temp:
        osDelay(10);
    }
}